package com.baihui.taobao.transition;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.log4j.Logger;

import com.baihui.taobao.AppConstants;
import com.baihui.taobao.authorize.TaoBaoSessionInfo;
import com.baihui.taobao.db.GeneDAO;
import com.baihui.taobao.db.TradeDAO;
import com.baihui.taobao.util.Util;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.TaobaoObject;
import com.taobao.api.internal.mapping.ApiField;
import com.taobao.api.internal.mapping.ApiListField;

/**
 * Created by Kevin.
 * User: HSZM1106-0312
 * Date: 11-12-30
 * Time: 下午10:41
 * 淘宝提供了三种授权方式：container容器登陆流程，基于OAuth2.0的登录验证授权流程，基于淘宝开放平台技术标准登录验证授权流程
 */
public class Cases {
    
    Logger logger = Logger.getLogger(getClass());

    public Cases(TaoBaoSessionInfo info) {
        this.sessionInfo = info;
    }

    protected TaoBaoSessionInfo sessionInfo;

    protected TaobaoClient getTaoBaoClient() {
        return new DefaultTaobaoClient(AppConstants.TAOBAOONLINEURL, sessionInfo.getAppKey(), sessionInfo.getAppSecret());
    }

    public TaoBaoSessionInfo getSessionInfo() {
        return sessionInfo;
    }

    private long startLogTime;

    public void logStart() {
        startLogTime = System.currentTimeMillis();
    }

    public void logEnd(String info) {
        long endLogTime = System.currentTimeMillis();
        logger.info(info + "总共耗时:" + (endLogTime - startLogTime) / 1000 + "秒！");
    }
    
    public void log(String info){
        logger.info(info);
    }

    /**
     * serviceName: taobao.user.get
     * 另外一种调用服务的方式
     *
     * @param serviceName
     * @param apiparamsMap
     * @return
     */
    public String invoke(String serviceName, String fields, TreeMap<String, String> apiparamsMap) {
        if (apiparamsMap == null) apiparamsMap = new TreeMap<String, String>();
        apiparamsMap.put("format", "json");
        apiparamsMap.put("method", serviceName);
        apiparamsMap.put("sign_method", "md5");
        apiparamsMap.put("app_key", sessionInfo.getAppKey());
        apiparamsMap.put("session", sessionInfo.getTopSession());
        apiparamsMap.put("v", "2.0");
        String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis()));
        apiparamsMap.put("timestamp", timestamp);
        apiparamsMap.put("fields", fields);//需要获取的字段

        //生成签名
        String sign = Util.md5Signature(apiparamsMap, sessionInfo.getAppSecret());
        apiparamsMap.put("sign", sign);
        StringBuilder param = new StringBuilder();
        for (Iterator<Map.Entry<String, String>> it = apiparamsMap.entrySet()
                .iterator(); it.hasNext(); ) {
            Map.Entry<String, String> e = it.next();
            param.append("&").append(e.getKey()).append("=").append(e.getValue());
        }
        return Util.getResult(AppConstants.TAOBAOONLINEURL, param.toString().substring(1));
    }
    
    public Date addMonths(Date date, int amount) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, amount);
		return c.getTime();
	}

    /**
     * 根据
     *
     * @param domainClass
     * @return
     * @throws Exception
     */
    public String parseFields(Class domainClass) throws Exception {
        StringBuilder fields = new StringBuilder();
        innerParseFields(fields, domainClass, "");
        String ret = fields.toString();
        if (ret.endsWith(",")) {
            ret = ret.substring(0, ret.length() - 1);
        }
        return ret;
    }

    public void innerParseFields(StringBuilder fields, Class domainClass, String prex) throws Exception {
        try {
            prex = (prex == null) ? "" : prex;

            BeanInfo beanInfo = Introspector.getBeanInfo(domainClass, Object.class);
            PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : descriptors) {
                Field field = domainClass.getDeclaredField(pd.getName());
                if (Util.isExist(field.getName(), GeneDAO.excludefield)) {
                    continue;
                }
                ApiField apiField = field.getAnnotation(ApiField.class);
                if (apiField != null) {
                    if (field.getType().getSimpleName().toUpperCase().equals("LIST")) {
                        ApiListField listField = field.getAnnotation(ApiListField.class);
                        if (listField != null) {
                            Type fieldType = field.getGenericType();
                            if (fieldType instanceof ParameterizedType) {
                                ParameterizedType paramType = (ParameterizedType) fieldType;
                                Type[] genericTypes = paramType.getActualTypeArguments();
                                if (genericTypes != null && genericTypes.length > 0) {
                                    if (genericTypes[0] instanceof Class<?>) {
                                        Class<?> subType = (Class<?>) genericTypes[0];
                                        innerParseFields(fields, subType, listField.value());
                                    }
                                }
                            }
                        }
                    } else {
                        if ("".equals(prex)) {
                            fields.append(apiField.value()).append(",");
                        } else {
                            fields.append(prex + "." + apiField.value()).append(",");
                        }

                    }
                }
            }
        } catch (IntrospectionException e) {
            throw new Exception(e);
        }
    }

    /**
     * 从List中过滤已经存在于数据库中的记录.
     * @param taobaoobjects
     * @param key
     * @param table
     * @return
     * @throws Exception
     */
    public List filter(List taobaoobjects, String key, String table) throws Exception {
        List ret = new ArrayList();
        StringBuilder ids = new StringBuilder();
        Object id = null;
        TaobaoObject info = null;
        for (int i = 0; i < taobaoobjects.size(); i++) {
            TaobaoObject taobaoObject = (TaobaoObject) taobaoobjects.get(i);
            if (info == null) info = taobaoObject;
            id =  PropertyUtils.getProperty(taobaoObject, key);
            if (id != null) {
                if (i < taobaoobjects.size() - 1) {
                    ids.append(id + ",");
                } else {
                    ids.append(id);
                }
            }
        }
        if (info != null) {
        	String strids = ids.toString();
        	if(strids.lastIndexOf(",") == strids.length() - 1){
        		strids = strids.substring(0,strids.lastIndexOf(","));
        	}
            String sql = "Select " + key + " from " + table + " where " + key + " in (" + strids + ")";
            TradeDAO tradeDAO = new TradeDAO();
            List existIds = tradeDAO.findAllObject(sql);
            if (existIds != null && existIds.size() > 0) {
                java.util.Iterator iterator = existIds.iterator();
                while (iterator.hasNext()) {
                    Map map = (Map) iterator.next();
                    ret.add(map.get(key));
                }
            }
        }
        return ret;
    }

}
